use std::sync::Arc;
use std::time::Instant;
use anyhow::Result;

use crate::di::{ServiceContainer, services::ConfigService};
use crate::config::{Configs, Server, DataBase, Log, Jwt, Cert};

/// 性能对比：零动态分发 vs 传统 trait-based 设计

/// 创建测试配置
fn create_test_config() -> Configs {
    Configs {
        server: Server {
            name: "perf-test-server".to_string(),
            address: "127.0.0.1:8080".to_string(),
            ssl: false,
        },
        database: DataBase {
            database_url: "sqlite::memory:".to_string(),
        },
        log: Log {
            filter_level: "info".to_string(),
            with_ansi: true,
            to_stdout: true,
            directory: "./logs".to_string(),
            file_name: "perf-test.log".to_string(),
            rolling: "daily".to_string(),
        },
        jwt: Jwt {
            jwt_secret: "perf_test_secret".to_string(),
            jwt_exp: 3600,
        },
        cert: Cert {
            cert: "perf-test.pem".to_string(),
            key: "perf-test.key".to_string(),
        },
    }
}

// ============================================================================
// 我们的零动态分发设计
// ============================================================================

/// 具体类型的服务 - 零动态分发
#[derive(Debug)]
pub struct ConcreteUserService {
    config: Arc<ConfigService>,
    user_count: u64,
}

impl ConcreteUserService {
    pub fn new(config: Arc<ConfigService>) -> Self {
        Self {
            config,
            user_count: 0,
        }
    }
    
    /// 这个方法可以被编译器内联
    #[inline]
    pub fn get_server_name(&self) -> &str {
        &self.config.config().server.name
    }
    
    /// 这个方法可以被编译器优化
    #[inline]
    pub fn process_user(&self, user_id: u64) -> String {
        format!("Processing user {} on server {}", user_id, self.get_server_name())
    }
    
    /// 批量处理 - 编译器可以向量化
    pub fn process_users(&self, user_ids: &[u64]) -> Vec<String> {
        user_ids.iter()
            .map(|&id| self.process_user(id))
            .collect()
    }
}

// ============================================================================
// 传统的 trait-based 设计（用于对比）
// ============================================================================

/// 传统的 trait 定义 - 会导致动态分发
pub trait UserServiceTrait {
    fn get_server_name(&self) -> &str;
    fn process_user(&self, user_id: u64) -> String;
    fn process_users(&self, user_ids: &[u64]) -> Vec<String>;
}

/// 实现 trait 的具体类型
#[derive(Debug)]
pub struct TraitBasedUserService {
    config: Arc<ConfigService>,
    user_count: u64,
}

impl TraitBasedUserService {
    pub fn new(config: Arc<ConfigService>) -> Self {
        Self {
            config,
            user_count: 0,
        }
    }
}

impl UserServiceTrait for TraitBasedUserService {
    fn get_server_name(&self) -> &str {
        &self.config.config().server.name
    }
    
    fn process_user(&self, user_id: u64) -> String {
        format!("Processing user {} on server {}", user_id, self.get_server_name())
    }
    
    fn process_users(&self, user_ids: &[u64]) -> Vec<String> {
        user_ids.iter()
            .map(|&id| self.process_user(id))
            .collect()
    }
}

// ============================================================================
// 性能测试
// ============================================================================

/// 性能测试结果
#[derive(Debug)]
pub struct PerformanceResult {
    pub test_name: String,
    pub iterations: u64,
    pub total_duration_ns: u64,
    pub avg_duration_ns: f64,
    pub ops_per_second: f64,
}

impl PerformanceResult {
    pub fn new(test_name: String, iterations: u64, total_duration_ns: u64) -> Self {
        let avg_duration_ns = total_duration_ns as f64 / iterations as f64;
        let ops_per_second = 1_000_000_000.0 / avg_duration_ns;
        
        Self {
            test_name,
            iterations,
            total_duration_ns,
            avg_duration_ns,
            ops_per_second,
        }
    }
    
    pub fn print(&self) {
        println!("📊 {}", self.test_name);
        println!("   迭代次数: {}", self.iterations);
        println!("   总耗时: {:.2}ms", self.total_duration_ns as f64 / 1_000_000.0);
        println!("   平均耗时: {:.2}ns", self.avg_duration_ns);
        println!("   每秒操作数: {:.0}", self.ops_per_second);
        println!();
    }
}

/// 测试具体类型调用性能（零动态分发）
pub fn benchmark_concrete_type_calls(iterations: u64) -> Result<PerformanceResult> {
    let container = ServiceContainer::new();
    let config = create_test_config();
    
    // 注册服务
    container.register_singleton::<ConfigService, _>(move |_| {
        Ok(ConfigService::new(config.clone()))
    })?;
    
    container.register_singleton::<ConcreteUserService, _>(|container| {
        let config = container.resolve::<ConfigService>()?;
        Ok(ConcreteUserService::new(config))
    })?;
    
    // 解析服务
    let user_service = container.resolve::<ConcreteUserService>()?;
    
    // 预热
    for i in 0..1000 {
        let _ = user_service.process_user(i);
    }
    
    // 性能测试
    let start = Instant::now();
    for i in 0..iterations {
        let _ = user_service.process_user(i);
    }
    let duration = start.elapsed();
    
    Ok(PerformanceResult::new(
        "具体类型调用 (零动态分发)".to_string(),
        iterations,
        duration.as_nanos() as u64,
    ))
}

/// 测试 trait 对象调用性能（动态分发）
pub fn benchmark_trait_object_calls(iterations: u64) -> Result<PerformanceResult> {
    let container = ServiceContainer::new();
    let config = create_test_config();
    
    // 注册服务
    container.register_singleton::<ConfigService, _>(move |_| {
        Ok(ConfigService::new(config.clone()))
    })?;
    
    let config_service = container.resolve::<ConfigService>()?;
    
    // 创建 trait 对象 - 这里会有动态分发
    let user_service: Arc<dyn UserServiceTrait> = Arc::new(TraitBasedUserService::new(config_service));
    
    // 预热
    for i in 0..1000 {
        let _ = user_service.process_user(i);
    }
    
    // 性能测试
    let start = Instant::now();
    for i in 0..iterations {
        let _ = user_service.process_user(i); // 动态分发调用
    }
    let duration = start.elapsed();
    
    Ok(PerformanceResult::new(
        "Trait 对象调用 (动态分发)".to_string(),
        iterations,
        duration.as_nanos() as u64,
    ))
}

/// 测试批量操作性能
pub fn benchmark_batch_operations(iterations: u64) -> Result<(PerformanceResult, PerformanceResult)> {
    let container = ServiceContainer::new();
    let config = create_test_config();
    
    // 注册服务
    container.register_singleton::<ConfigService, _>(move |_| {
        Ok(ConfigService::new(config.clone()))
    })?;
    
    container.register_singleton::<ConcreteUserService, _>(|container| {
        let config = container.resolve::<ConfigService>()?;
        Ok(ConcreteUserService::new(config))
    })?;
    
    let concrete_service = container.resolve::<ConcreteUserService>()?;
    let config_service = container.resolve::<ConfigService>()?;
    let trait_service: Arc<dyn UserServiceTrait> = Arc::new(TraitBasedUserService::new(config_service));
    
    let user_ids: Vec<u64> = (0..100).collect();
    
    // 测试具体类型批量操作
    let start = Instant::now();
    for _ in 0..iterations {
        let _ = concrete_service.process_users(&user_ids);
    }
    let concrete_duration = start.elapsed();
    
    // 测试 trait 对象批量操作
    let start = Instant::now();
    for _ in 0..iterations {
        let _ = trait_service.process_users(&user_ids);
    }
    let trait_duration = start.elapsed();
    
    Ok((
        PerformanceResult::new(
            "具体类型批量操作".to_string(),
            iterations,
            concrete_duration.as_nanos() as u64,
        ),
        PerformanceResult::new(
            "Trait 对象批量操作".to_string(),
            iterations,
            trait_duration.as_nanos() as u64,
        ),
    ))
}

/// 运行完整的性能对比测试
pub async fn run_performance_comparison() -> Result<()> {
    println!("🚀 开始性能对比测试");
    println!("{}", "=".repeat(60));
    
    let iterations = 1_000_000;
    
    println!("🔧 测试配置:");
    println!("   迭代次数: {}", iterations);
    println!("   测试项目: 单次调用、批量操作");
    println!();
    
    // 1. 单次调用性能对比
    println!("📈 单次调用性能对比:");
    
    let concrete_result = benchmark_concrete_type_calls(iterations)?;
    concrete_result.print();
    
    let trait_result = benchmark_trait_object_calls(iterations)?;
    trait_result.print();
    
    let speedup = trait_result.avg_duration_ns / concrete_result.avg_duration_ns;
    println!("⚡ 具体类型比 trait 对象快 {:.2}x", speedup);
    println!();
    
    // 2. 批量操作性能对比
    println!("📈 批量操作性能对比 (每次处理100个用户):");
    
    let (concrete_batch, trait_batch) = benchmark_batch_operations(iterations / 100)?;
    concrete_batch.print();
    trait_batch.print();
    
    let batch_speedup = trait_batch.avg_duration_ns / concrete_batch.avg_duration_ns;
    println!("⚡ 具体类型批量操作比 trait 对象快 {:.2}x", batch_speedup);
    println!();
    
    // 3. 内存使用对比
    println!("💾 内存使用对比:");
    println!("   Arc<ConcreteUserService>: {} bytes", std::mem::size_of::<Arc<ConcreteUserService>>());
    println!("   Arc<dyn UserServiceTrait>: {} bytes", std::mem::size_of::<Arc<dyn UserServiceTrait>>());
    println!("   差异: trait 对象需要额外的 vtable 指针");
    println!();
    
    println!("✅ 性能对比测试完成！");
    println!("{}", "=".repeat(60));
    
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_performance_comparison() {
        run_performance_comparison().await.unwrap();
    }
    
    #[test]
    fn test_concrete_type_benchmark() {
        let result = benchmark_concrete_type_calls(10000).unwrap();
        assert!(result.avg_duration_ns > 0.0);
        println!("Concrete type benchmark: {:.2}ns per call", result.avg_duration_ns);
    }
    
    #[test]
    fn test_trait_object_benchmark() {
        let result = benchmark_trait_object_calls(10000).unwrap();
        assert!(result.avg_duration_ns > 0.0);
        println!("Trait object benchmark: {:.2}ns per call", result.avg_duration_ns);
    }
}
